package com.xiaoq.order.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.mongodb.DuplicateKeyException;
import com.xiaoq.apis.interpreter.IInterpreterApi;
import com.xiaoq.apis.interpreter.InterCalendar4OrderVo;
import com.xiaoq.apis.interpreter.Interpreter4OrderVo;
import com.xiaoq.apis.sites.ISitesApi;
import com.xiaoq.apis.sites.SitesInfo4SocialVo;
import com.xiaoq.apis.user.IUserApi;
import com.xiaoq.apis.user.UserInfo4UserCouponVo;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.distribution.entity.TicketOrderItemEntity;
import com.xiaoq.distribution.service.ITicketOrderItemService;
import com.xiaoq.order.entity.*;
import com.xiaoq.order.entity.OrderState;
import com.xiaoq.order.service.IShopOrderCardService;
import com.xiaoq.order.service.IShopOrderService;
import com.xiaoq.order.vo.*;
import com.xiaoq.shop.entity.*;
import com.xiaoq.shop.service.ISKUService;
import com.xiaoq.shop.service.IShopPayTypeService;
import com.xiaoq.shop.service.IUserCouponService;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/api/v1/orders")
@Api(tags = "C端购票订单的提交、删除、取消等")
class UserOrderEndpoint2C {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserOrderEndpoint2C.class);
    private static final class ConfirmPayResponse extends GenericDataResponse<ConfirmPayVo> {}
    private static final class GoPayResponse extends GenericDataResponse<GoPayVo> {}
    private static final class ShopOrderResponse extends GenericListResponse<ShopOrderVo> {}
    private static final class ShopOrderDataResponse extends GenericDataResponse<ShopOrderVo> {}
    private static final class PrePayOrderDataResponse extends GenericDataResponse<PrePayOrder> {}
    private static final class ShopOrderTicketDataResponse extends GenericDataResponse<ShopOrderTicketVo> {}

    @Autowired
    private IUserCouponService userCouponService;

    @Autowired
    private IShopOrderService shopOrderService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private ISKUService skuService;

    @Autowired
    private IShopPayTypeService shopPayTypeService;

    @Autowired
    private IShopOrderCardService shopOrderCardService;

    @Autowired
    private ITicketOrderItemService ticketOrderItemService;

    @Reference(interfaceClass=IUserApi.class, check=false, version="1.0.0")
    private IUserApi userDubboApi;

    @Reference(interfaceClass=IInterpreterApi.class, check=false, version="1.0.0")
    private IInterpreterApi interpreterApi;

    @Reference(interfaceClass=ISitesApi.class, check=false, version="1.0.0")
    private ISitesApi sitesApi;

    @ApiOperation(value="提交订单", notes="提交订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GoPayResponse.class, message = "提交订单")
    })
    @PostMapping(value = "", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?>  commitOrder(
            HttpServletRequest request,
            @RequestBody ShopOrderAddition shopOrderAddition) {

        //1、判断用户存在
        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }

        if(userInfo4UserCouponVo.isAnonymous()){
            return GenericResponse.ng("此帐户为匿名登录,暂不能购票,请注册后购票");
        }

        List<ShoppingItemAddition> shoppingItems = shopOrderAddition.getShoppingItems();
        if(CollectionUtils.isEmpty(shoppingItems)){
            return GenericResponse.ng("暂无发现有效订单");
        }

        SitesInfo4SocialVo siteInfo4Social = sitesApi.getSiteInfo4Social(shopOrderAddition.getShopId());
        if(siteInfo4Social==null || StringUtils.isBlank(siteInfo4Social.getName())){
            return GenericResponse.ng("此景区不存在");
        }

        //因为是买门票，目前最多只能买一种SKU
        ShoppingItemAddition shoppingItem = shoppingItems.get(0);
        String spuCode = shoppingItem.getSpuCode();
        String skuCode = shoppingItem.getSkuCode();
        String shopId = shopOrderAddition.getShopId();
        String orderNo = idGenerator.nextId();
        ShopOrderEntity shopOrderEntity = new ShopOrderEntity();
        ShoppingItem newShoppingItem = new ShoppingItem();
        shopOrderEntity.setShopId(shopId);
        shopOrderEntity.setUserId(userId);
        shopOrderEntity.setCellphoneNumber(shopOrderAddition.getCellphoneNumber());
        shopOrderEntity.setCouponCode(shopOrderAddition.getCouponCode());
        shopOrderEntity.setUserCounponId(shopOrderAddition.getUserCouponId());
        shopOrderEntity.setOrderState(OrderState.WAITPAY.value()); //设置为待付款
        shopOrderEntity.setUserRealName(shopOrderAddition.getUserRealName());
        shopOrderEntity.setPayState(PayState.NOPAYMENT.value()); //设置为待付款
        shopOrderEntity.setShopName(siteInfo4Social.getName());
        shopOrderEntity.setCreateTime(System.currentTimeMillis());
        shopOrderEntity.setUserDeleteFlag(ConstantUtil.NOT_DELETE_STATUS); //设置为未删除
        shopOrderEntity.setPayEndTime(new DateTime().plusMinutes(30).getMillis()); //倒计时30分钟
        shopOrderEntity.setOrderType(ConstantUtil.ORDER_TYPE_TICKET);

        SKUEntity skuEntity = skuService.getTicketSku(shopId, spuCode, skuCode);
        if(skuEntity == null || skuEntity.getSaleState() == null || skuEntity.getSaleState() == ConstantUtil.SALE_STATE_OFF){
            return GenericResponse.ng("此票已下线");
        }

        //TODO 暂时未添加身份证信息
        /*String idCard = shopOrderAddition.getIdCard(); //需替换
        IdcardInfoExtractor idcardInfoExtractor = IdcardValidator.getIdcardInfo(idCard);
        if(idcardInfoExtractor == null){
            return GenericResponse.ng("身份证信息不合法");
        }else {
            ShopOrderCardEntity shopOrderCardEntity = new ShopOrderCardEntity();
            shopOrderCardEntity.setIdCard(idCard);
            shopOrderCardEntity.setId(idGenerator.nextId());
            shopOrderCardEntity.setBirthday(idcardInfoExtractor.getBirthday());
            shopOrderCardEntity.setComeFrom(idcardInfoExtractor.getProvince());
            shopOrderCardEntity.setGender(idcardInfoExtractor.getGenderInt());
            shopOrderCardEntity.setShopId(shopId);
            shopOrderCardEntity.setShopOrderId(orderNo);
            shopOrderCardEntity.setUserId(userId);
            shopOrderCardService.save(shopOrderCardEntity);
        }*/

        newShoppingItem.setNumber(shoppingItem.getNumber());
        newShoppingItem.setSpuCode(skuEntity.getSpuCode());
        newShoppingItem.setSpuName(skuEntity.getSpuName());
        newShoppingItem.setImageUrlOfSKU(skuEntity.getImageUrlOfSKU());
        newShoppingItem.setSkuCode(skuEntity.getSkuCode());
        newShoppingItem.setSpecifications(skuEntity.getSpecifications());
        newShoppingItem.setPrice(skuEntity.getPrice());
        newShoppingItem.setDiscountPrice(skuEntity.getDiscountPrice());

        Integer max2PermitPurchased = skuEntity.getMax2PermitPurchased();
        if(max2PermitPurchased == null || max2PermitPurchased==0){
            //不限制购买数量
        }else if(max2PermitPurchased < shoppingItem.getNumber()){
            return GenericResponse.ng("超过限制购买的数量");
        }
        //判断预售天数
        int preSalePeriod = skuEntity.getPreSalePeriod(); //票的预售天数
        DateTime today = new DateTime();
        DateTime todayBegin = new DateTime(today.getYear(),
                today.getMonthOfYear(),
                today.getDayOfMonth(),
                0,
                0);
        DateTime todayEnd = todayBegin.plusDays(1);
        DateTime travelDate = new DateTime(shoppingItem.getTravelDate()).plusMillis(today.getMillisOfDay());
        //购买今日的门票
        if(travelDate.getMillis() < todayEnd.getMillis()){
            //判断是否有16点之前能购买
            List<TicketTag> ticketTags = skuEntity.getTicketLabels();
            if(CollectionUtils.isNotEmpty(ticketTags)){
                for(TicketTag ticketTag : ticketTags){
                    //16点可够今日门票
                    if(StringUtils.equals(ticketTag.getId(), "1")){
                        String title = ticketTag.getTitle();  //title 格式为 16:00
                        String hourOfDayStr = "";
                        if(StringUtils.isNotBlank(title) && title.contains(":") && StringUtils.isNumeric(hourOfDayStr = title.split(":")[0])){
                            int hourOfDay = Integer.parseInt(hourOfDayStr);
                            DateTime today16EndTime = new DateTime(today.getYear(),
                                    today.getMonthOfYear(),
                                    today.getDayOfMonth(),
                                    hourOfDay,  //暂时为16点截止
                                    0);
                            if(today16EndTime.getMillis() < travelDate.getMillis()){
                                return GenericResponse.ng("不能购买今日门票");
                            }
                        }
                    }
                }
            }
        }

        DateTime purchaseMaxDate = todayBegin.plusDays(preSalePeriod);
        if(travelDate.getMillis() >= todayBegin.getMillis()
                && travelDate.getMillis() <= purchaseMaxDate.getMillis()){
            newShoppingItem.setTravelDate(travelDate.getMillis());
        }else {
            return GenericResponse.ng("购票时间超过预售期时间");
        }

        shopOrderEntity.setTotalAmount(newShoppingItem.getDiscountPrice()/100.0 * shoppingItem.getNumber());
        boolean useCoupon = false;
        //优惠券相关
        long currentMillis = System.currentTimeMillis();
        String userCouponId = shopOrderAddition.getUserCouponId();//用户优惠券ID
        if(StringUtils.isNotBlank(userCouponId)){
            UserCouponEntity userCouponEntity = userCouponService.getUserCouponById(userCouponId);
            //判断优惠券是否过期
            if(userCouponEntity!=null && StringUtils.equals(userId, userCouponEntity.getUserId())
                    && UserCouponEntity.StateEnum.NOUSE.value()==userCouponEntity.getState()
                    && currentMillis<userCouponEntity.getExpirationDate()
                    && userCouponEntity.getEffectiveDate() < currentMillis){

                //判断优惠券类型。是否满减或者直接减金额
                if(shopOrderEntity.getTotalAmount() >= userCouponEntity.getMinSpendingAmountForUse()){
                    useCoupon = true;
                    //设置总金额
                    shopOrderEntity.setTotalAmount(shopOrderEntity.getTotalAmount() - userCouponEntity.getDenomination());
                    shopOrderEntity.setTotalMoneyOfUsedCoupons(userCouponEntity.getDenomination());
                }
            }
        }
        List<ShoppingItem> shoppingItemList = Arrays.asList(newShoppingItem);
        shopOrderEntity.setShoppingItems(shoppingItemList);

        try {
            shopOrderEntity.setId(idGenerator.nextId());
            shopOrderEntity.setShopOrderId(orderNo);
            shopOrderService.saveShopOrder(shopOrderEntity);
            saveTicketCodeAndReturn(shopOrderEntity, skuEntity);
            //锁定优惠券
            if(useCoupon) {
                userCouponService.lockUserCoupon(userCouponId, userId);
            }
            GoPayVo goPayVo = new GoPayVo();
            goPayVo.setOrderNo(orderNo);
            return GoPayResponse.okWithData(goPayVo);

        }catch (Exception e){
            //释放优惠券
            if(useCoupon) {
                userCouponService.releaseUserCoupon(userCouponId, userId);
            }
            //TODO 如果订单存在，删除订单
            LOGGER.error(e.getMessage());
        }
        LOGGER.error("订单提交失败");
        return GenericResponse.ng("订单提交失败");
    }


    private void saveTicketCodeAndReturn(ShopOrderEntity shopOrderEntity, SKUEntity skuEntity){
        List<ShoppingItem> shoppingItemList = shopOrderEntity.getShoppingItems();
        if(CollectionUtils.isNotEmpty(shoppingItemList)){
            int ticketCount = 0;
            for(ShoppingItem item : shoppingItemList){
                ticketCount += item.getNumber();
            }
            ShoppingItem item = shoppingItemList.get(0);

            for(int i = 0; i < ticketCount; i++){
                // 因为目前只能买一种票
                TicketOrderItemEntity ticketOrderItemEntity = new TicketOrderItemEntity();
                ticketOrderItemEntity.setShopOrderId(shopOrderEntity.getShopId());
                String orderItemId = idGenerator.nextId();
                ticketOrderItemEntity.setId(orderItemId);
                ticketOrderItemEntity.setShopOrderId(shopOrderEntity.getShopOrderId());
                ticketOrderItemEntity.setNumber(1);
                ticketOrderItemEntity.setPayState(shopOrderEntity.getPayState());
                ticketOrderItemEntity.setOrderState(shopOrderEntity.getOrderState());
                ticketOrderItemEntity.setSettleStatus(ConstantUtil.SETTLE_STATUS_WAIT);
                ticketOrderItemEntity.setCreateTime(System.currentTimeMillis());
                ticketOrderItemEntity.setTicketId(skuEntity.getId());
                ticketOrderItemEntity.setTicketName(item.getSpuName());
                ticketOrderItemEntity.setTourName(shopOrderEntity.getUserRealName());
                ticketOrderItemEntity.setShopId(shopOrderEntity.getShopId());
                String ticketCode = Long.toHexString(System.nanoTime());
                //保存到数据库
                ticketOrderItemEntity.setTicketCode(ticketCode);  // ticketCode唯一索引
                try {
                    ticketOrderItemService.save(ticketOrderItemEntity);
                }catch (DuplicateKeyException e){
                    ticketCode = Long.toHexString(System.nanoTime());
                    ticketOrderItemEntity.setTicketCode(ticketCode);
                    ticketOrderItemService.save(ticketOrderItemEntity);
                }
            }
        }

//        Class
        return;
    }

    //获取用户的各种订单列表
    @ApiOperation(value="查询用户的订单列表", notes="查询用户的订单列表")
    @ApiResponses({
            @ApiResponse(code = 200, response = ShopOrderResponse.class, message = "查询用户的订单列表")
    })
    @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> findShopOrders(
            HttpServletRequest request,
            @ApiParam(required = true, name = "orderState", value = "订单状态:99,所有;0,已下单,待支付; 4,待使用;5,已完成;6,已评价")
            @RequestParam int orderState,
            @ApiParam(required = false, name = "payState", value = "支付状态:0,待支付;1,已支付;")
            @RequestParam(required = false) Integer payState
            /*,
            @ApiParam(required = true, name = "pagingTimeOfPreRecord", value = "分页用的时间戳")
            @RequestParam Long pagingTimeOfPreRecord,
            @ApiParam(required = true, name = "pageSize", value = "每页数据条数")
            @RequestParam int pageSize*/) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo = userDubboApi.getUserInfoById(userId);
        if(userInfo==null || StringUtils.isBlank(userInfo.getId())){
            return GenericResponse.ng("此用户不存在或未登录");
        }

        Integer orderStateInteger = orderState;
        Integer orderType = null;

        if(ConstantUtil.ORDER_TICKET_STATUS_HAVE_PAID.equals(orderState)){ //购票的订单，待使用
            orderType = ConstantUtil.ORDER_TYPE_TICKET; //待使用，目前只查询票
        }else if(orderState == OrderState.ALL.value()){ //查询全部订单
            orderStateInteger = null;
        }

        List<ShopOrderVo> shopOrderVoList = new ArrayList<>();

        List<ShopOrderEntity> orderEntityList = shopOrderService.getUserAllOrderByUserId(userId, payState, ConstantUtil.NOT_DELETE_STATUS,orderType,orderStateInteger);
        Map<String, ShopOrderEntity> orderId2Order = new LinkedHashMap<>();
        if(CollectionUtils.isEmpty(orderEntityList)){
            return ShopOrderResponse.listAndCount(shopOrderVoList, shopOrderVoList.size());
        }
        List<String> orderIdList = new ArrayList<>();
        for(ShopOrderEntity shopOrder : orderEntityList){
            if(StringUtils.isNotBlank(shopOrder.getInterpreterId())){
                orderIdList.add(shopOrder.getShopOrderId());
            }
            orderId2Order.put(shopOrder.getShopOrderId(), shopOrder);
        }

        List<InterCalendar4OrderVo> interCalendarList = null;
        if(CollectionUtils.isNotEmpty(orderIdList)){
            try {
                interCalendarList = interpreterApi.getInterCalendarList(orderIdList);
            }catch (Exception e){
                LOGGER.error(e.getMessage(), e);
                LOGGER.error("远程调用讲解员服务失败。userId: " + userId + "....");
            }
        }

        Map<String, InterCalendar4OrderVo> orderId2InterCalendarMap = null;
        if(CollectionUtils.isNotEmpty(interCalendarList)){
            orderId2InterCalendarMap = interCalendarList.stream().collect(Collectors.toMap(InterCalendar4OrderVo::getOrderId, calendarVo -> calendarVo));
        }
        if(orderId2InterCalendarMap == null){
            orderId2InterCalendarMap = new HashMap<>();
        }

        ShopOrderVo shopOrderVo = null;
        for(ShopOrderEntity shopOrder : orderEntityList){
            String shopOrderId = shopOrder.getShopOrderId();
            shopOrderVo = new ShopOrderVo();
            BeanUtils.copyProperties(shopOrder, shopOrderVo);
            if(orderId2InterCalendarMap.containsKey(shopOrderId)){
                shopOrderVo.setCalendarVo(orderId2InterCalendarMap.get(shopOrderId));
            }

            shopOrderVoList.add(shopOrderVo);
        }

        return ShopOrderResponse.listAndCount(shopOrderVoList, shopOrderVoList.size());
    }


    @ApiOperation(value="取消订单", notes="取消订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "取消订单")
    })
    @RequestMapping(value = "/{shopOrderId}/orderstate/canceled", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> cancelOrder(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderId(shopOrderId);
        if(shopOrderEntity==null || !StringUtils.equals(userId, shopOrderEntity.getUserId())){
            return GenericResponse.ng("订单不存在");
        }

        boolean cancelOrderResult = shopOrderService.cancelOrder(shopOrderId, userId);
        String interpreterId = shopOrderEntity.getInterpreterId();
        //TODO 如果是讲解员的订单，取消讲解员锁定
        if(cancelOrderResult){

            if(StringUtils.isNotBlank(interpreterId)){
                try {
                    boolean retFlag = interpreterApi.updateInter2CanAppoint(interpreterId, shopOrderEntity.getShopId());
                    interpreterApi.updateInterCalendarStatus(shopOrderId, ConstantUtil.INTERPRETER_CALENDAR_STATUS_CANCEL);
                    if(!retFlag){
                        LOGGER.error("取消订单时,修改讲解员到可预约状态失败! orderNo" + shopOrderId + ", userId: " + userId);
                    }
                }catch (Exception e){
                    LOGGER.error("解锁讲解员失败，interId: "+ interpreterId + ",order: " + shopOrderId + "," + e.getMessage(), e);
                }
            }

            return GenericResponse.ok();
        }else {
            return GenericResponse.ng("取消订单失败");
        }
    }

    //去付款的页面，选择可支付的方式，以及支付时间
    @ApiOperation(value="确认付款的页面（付款方式列表时间倒计时）", notes="确认付款的页面（付款方式列表时间倒计时）")
    @ApiResponses({
            @ApiResponse(code = 200, response = ConfirmPayResponse.class, message = "确认付款的页面（付款方式列表时间倒计时）")
    })
    @GetMapping(value = "/{shopOrderId}/orderstate/topay", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> toPayOrder(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        //1、判断用户存在
        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo == null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }

        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderById(shopOrderId, userId);
        if(shopOrderEntity == null){
            return GenericResponse.ng("该订单不存在");
        }

        String interMobile = "";
        if(StringUtils.isNotBlank(shopOrderEntity.getInterpreterId())){

            try {
                Interpreter4OrderVo interpreter4OrderVo = interpreterApi.getInterByInterId(shopOrderEntity.getInterpreterId());
                interMobile = (interpreter4OrderVo==null)?"":interpreter4OrderVo.getMobile();
            }catch (Exception e){
                LOGGER.error(e.getMessage(), e);
            }

        }

        int discountPrice = shopOrderEntity.getTotalMoneyOfUsedCoupons()==null?0:shopOrderEntity.getTotalMoneyOfUsedCoupons();
        ConfirmPayVo confirmPayVo = new ConfirmPayVo();
        confirmPayVo.setDiscountPrice(discountPrice + 0.0);
        ShopPayTypeEntity shopPayType = shopPayTypeService.getByShopId(shopOrderEntity.getShopId());
        confirmPayVo.setPayMethods(shopPayType.getPayMethods());
        confirmPayVo.setPayPrice(shopOrderEntity.getTotalAmount());
        confirmPayVo.setPayRemainTime((shopOrderEntity.getPayEndTime()-System.currentTimeMillis())/1000);
        confirmPayVo.setUserId(shopOrderEntity.getUserId());
        confirmPayVo.setShopOrderId(shopOrderEntity.getShopOrderId());
        confirmPayVo.setInterMobile(interMobile);

        return ConfirmPayResponse.okWithData(confirmPayVo);
    }

    //删除订单
    @ApiOperation(value="删除用户订单", notes="删除用户订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "删除购票订单")
    })
    @DeleteMapping(value = "/{shopOrderId}/orderstate/delete", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> deleteOrder(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        return getResponseEntity(request, shopOrderId);
    }

    @ApiOperation(value="(小程序)删除用户订单", notes="(小程序)删除用户订单")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "(小程序)删除购票订单")
    })
    @GetMapping(value = "/{shopOrderId}/orderstate/delete", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> deleteOrderGetByGet(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        return getResponseEntity(request, shopOrderId);
    }

    private ResponseEntity<?> getResponseEntity(HttpServletRequest request, @ApiParam(required = true, name = "shopOrderId", value = "订单id") @PathVariable String shopOrderId) {
        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo == null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        boolean delFlag = shopOrderService.deleteUserOrderByUserIdAndOrderId(userId, shopOrderId);
        if(delFlag){
            return GenericResponse.ok();
        }
        return GenericResponse.ng("删除订单失败");
    }

    @ApiOperation(value="获取订单详情", notes="获取订单详情")
    @ApiResponses({
            @ApiResponse(code = 200, response = ShopOrderDataResponse.class, message = "获取订单详情")
    })
    @GetMapping(value = "/{shopOrderId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> detail(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderId(shopOrderId);
        if(shopOrderEntity == null){
            return GenericResponse.ng("订单不存在");
        }

        String interpreterId = shopOrderEntity.getInterpreterId();
        Integer orderType = shopOrderEntity.getOrderType();
        if(ConstantUtil.ORDER_TYPE_TICKET.equals(orderType)){ //购买门票的订单

            ShopOrderVo shopOrderVo = new ShopOrderVo();
            BeanUtils.copyProperties(shopOrderEntity, shopOrderVo);
            //设置付款倒计时
            shopOrderVo.setPayRemainTime((shopOrderEntity.getPayEndTime()-System.currentTimeMillis())/1000);
            return ShopOrderDataResponse.okWithData(shopOrderVo);

        }else if(ConstantUtil.ORDER_TYPE_INTERPRETER.equals(orderType) && StringUtils.isNotBlank(interpreterId)){//预约讲解员的订单
            InterCalendar4OrderVo interCalendar4OrderVo = null;
            try {
                interCalendar4OrderVo = interpreterApi.getInterCalendar(shopOrderId);
            }catch (Exception e){
                LOGGER.error(e.getMessage(), e);
                LOGGER.error("获取讲解员订单详情日历失败。orderId: " + shopOrderId + ", interId: " + interpreterId + ",uerId: " + userId);
            }

            ShopOrderVo shopOrderVo = new ShopOrderVo();
            BeanUtils.copyProperties(shopOrderEntity, shopOrderVo);
            shopOrderVo.setCalendarVo(interCalendar4OrderVo);
            //设置付款倒计时
            shopOrderVo.setPayRemainTime((shopOrderEntity.getPayEndTime()-System.currentTimeMillis())/1000);
            return ShopOrderDataResponse.okWithData(shopOrderVo);
        }

        return GenericResponse.ng("获取订单详情失败，orderId: " + shopOrderId + ", userId: " + userId);
    }

    @ApiOperation(value="提交订单时，计算订单价格", notes="提交订单时，计算订单价格")
    @ApiResponses({
            @ApiResponse(code = 200, response = PrePayOrderDataResponse.class, message = "提交订单时，计算订单价格")
    })
    @PostMapping(value = "/calculateorder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?>  commitOrder2Calculate(
            HttpServletRequest request,
            @RequestBody ShopOrderAddition shopOrderAddition) {

        //1、判断用户存在
        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }

        if(userInfo4UserCouponVo.isAnonymous()){
            return GenericResponse.ng("此帐户为匿名登录,暂不能购票,请注册后购票");
        }

        List<ShoppingItemAddition> shoppingItems = shopOrderAddition.getShoppingItems();
        if(CollectionUtils.isEmpty(shoppingItems)){
            return GenericResponse.ng("暂无发现有效订单");
        }

        //因为是买门票，目前最多只能买一种SKU
        ShoppingItemAddition shoppingItem = shoppingItems.get(0);
        String spuCode = shoppingItem.getSpuCode();
        String skuCode = shoppingItem.getSkuCode();
        String shopId = shopOrderAddition.getShopId();

        SKUEntity skuEntity = skuService.getTicketSku(shopId, spuCode, skuCode);
        if(skuEntity == null || StringUtils.isBlank(skuEntity.getId())){
            return GenericResponse.ng("此商品不存在或者已下架");
        }

        Integer max2PermitPurchased = skuEntity.getMax2PermitPurchased();
        if(max2PermitPurchased == null || max2PermitPurchased==0){
            //不限制购买数量
        }else if(max2PermitPurchased < shoppingItem.getNumber()){
            return GenericResponse.ng("超过限制购买的数量");
        }
        //判断预售天数
        int preSalePeriod = skuEntity.getPreSalePeriod(); //票的预售天数
        DateTime today = new DateTime();
        DateTime todayBegin = new DateTime(today.getYear(),
                today.getMonthOfYear(),
                today.getDayOfMonth(),
                0,
                0);
        DateTime todayEnd = todayBegin.plusDays(1);
        DateTime travelDate = new DateTime(shoppingItem.getTravelDate()).plusMillis(today.getMillisOfDay());

        DateTime purchaseMaxDate = todayBegin.plusDays(preSalePeriod);
        if(travelDate.getMillis() >= todayBegin.getMillis()
                && travelDate.getMillis() <= purchaseMaxDate.getMillis()){
        }else {
            return GenericResponse.ng("出游购票时间未选或购票时间超过预售期时间");
        }

        double totalAmount = (int)(skuEntity.getDiscountPrice()/100.0 * shoppingItem.getNumber());

        //优惠券相关
        long currentMillis = System.currentTimeMillis();
        String userCouponId = shopOrderAddition.getUserCouponId();//用户优惠券ID
        if(StringUtils.isNotBlank(userCouponId)){
            UserCouponEntity userCouponEntity = userCouponService.getUserCouponById(userCouponId);
            //判断优惠券是否过期
            if(userCouponEntity!=null && StringUtils.equals(userId, userCouponEntity.getUserId())
                    && UserCouponEntity.StateEnum.NOUSE.value()==userCouponEntity.getState()
                    && currentMillis<userCouponEntity.getExpirationDate()
                    && userCouponEntity.getEffectiveDate() < currentMillis){

                //判断优惠券类型。是否满减或者直接减金额
                if(totalAmount >= userCouponEntity.getMinSpendingAmountForUse()){
                    //设置总金额
                    totalAmount = (totalAmount - userCouponEntity.getDenomination());
                }
            }
        }

        if(totalAmount <= 0.0){
            return GenericResponse.ng("最终价格必须大于0");
        }
        PrePayOrder prePayOrder = new PrePayOrder();
        prePayOrder.setTotalAmount(totalAmount);
        return PrePayOrderDataResponse.okWithData(prePayOrder);
    }


    @ApiOperation(value="获取我的门票", notes="获取我的门票")
    @ApiResponses({
            @ApiResponse(code = 200, response = ShopOrderTicketDataResponse.class, message = "获取我的门票")
    })
    @GetMapping(value = "/{shopOrderId}/ticket", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> myticket(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id") @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderId(shopOrderId);
        if(shopOrderEntity == null){
            return GenericResponse.ng("订单不存在");
        }
        if(!StringUtils.equals(shopOrderEntity.getUserId(), userId)){
            return GenericResponse.ng("用户和订单不匹配");
        }

        List<ShoppingItem> orderItemList = shopOrderEntity.getShoppingItems();
        if(CollectionUtils.isEmpty(orderItemList)){
            return GenericResponse.ng("订单项不存在");
        }

        int ticketCount = 0;
        String spuName = "";
        Long travelDate = 0L;
        for(ShoppingItem shoppingItem : orderItemList){
            ticketCount += shoppingItem.getNumber();
            spuName = shoppingItem.getSpuName();
            travelDate = shoppingItem.getTravelDate();
        }

        List<String> ticketCodeList = new ArrayList<>();
        List<TicketOrderItemEntity> ticketOrderItemList = ticketOrderItemService.getListByShopOrderId(shopOrderId);
        if(CollectionUtils.isNotEmpty(ticketOrderItemList)){
            for(TicketOrderItemEntity ticketOrderItemEntity : ticketOrderItemList){
                ticketCodeList.add(ticketOrderItemEntity.getTicketCode());
            }
        }else {
            for(int i=0;i<ticketCount;i++){
                ticketCodeList.add(Long.toHexString(System.nanoTime()));
            }
        }

        ShopOrderTicketVo shopOrderTicketVo = new ShopOrderTicketVo();
        shopOrderTicketVo.setShopId(shopOrderEntity.getShopId());
        shopOrderTicketVo.setShopName(shopOrderEntity.getShopName());
        shopOrderTicketVo.setShopOrderId(shopOrderEntity.getShopOrderId());
        shopOrderTicketVo.setTotalAmount(shopOrderEntity.getTotalAmount());
        shopOrderTicketVo.setUserId(shopOrderEntity.getUserId());
        shopOrderTicketVo.setUserRealName(shopOrderEntity.getUserRealName());
        shopOrderTicketVo.setTravelDate(travelDate);
        shopOrderTicketVo.setSpuName(spuName);
        shopOrderTicketVo.setTicketCodeList(ticketCodeList);
        shopOrderTicketVo.setTicketCount(ticketCount);

        return ShopOrderTicketDataResponse.okWithData(shopOrderTicketVo);
    }

    @ApiOperation(value="将订单改为已使用", notes="将订单改为已使用")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "将订单改为已使用")
    })
    @RequestMapping(value = "/{shopOrderId}/orderstate/touse", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<?> updateOrder2Use(
            HttpServletRequest request,
            @ApiParam(required = true, name = "shopOrderId", value = "订单id")
            @PathVariable String shopOrderId) {

        String userId = (String) request.getAttribute("userId");
        UserInfo4UserCouponVo userInfo4UserCouponVo = userDubboApi.getUserInfoById(userId);
        if(userInfo4UserCouponVo==null || StringUtils.isBlank(userInfo4UserCouponVo.getId())){
            return GenericResponse.ng("此用户未登录或不存在");
        }
        ShopOrderEntity shopOrderEntity = shopOrderService.getShopOrderByOrderId(shopOrderId);
        if(shopOrderEntity==null){
            return GenericResponse.ng("订单不存在");
        }

//        if(!StringUtils.equals(userId, shopOrderEntity.getUserId()){
//            return GenericResponse.ng("不是自己的订单");
//        }

        ShopOrderEntity updateOrder = new ShopOrderEntity();
        updateOrder.setShopOrderId(shopOrderId);
        updateOrder.setOrderState(ConstantUtil.ORDER_TICKET_STATUS_COMPLETE);

        boolean updateOrderResult = shopOrderService.updateShopOrderByOrderId(updateOrder);
        String interpreterId = shopOrderEntity.getInterpreterId();
            //TODO 如果是讲解员的订单，取消讲解员锁定
            if(updateOrderResult){

            if(StringUtils.isNotBlank(interpreterId)){
                try {
                    boolean retFlag = interpreterApi.updateInter2CanAppoint(interpreterId, shopOrderEntity.getShopId());
                    interpreterApi.updateInterCalendarStatus(shopOrderId, ConstantUtil.INTERPRETER_CALENDAR_STATUS_COMPLETE);
                    if(!retFlag){
                        LOGGER.error("取消订单时,修改讲解员到可预约状态失败! orderNo" + shopOrderId + ", userId: " + userId);
                    }
                }catch (Exception e){
                    LOGGER.error("解锁讲解员失败，interId: "+ interpreterId + ",order: " + shopOrderId + "," + e.getMessage(), e);
                }
            }

            return GenericResponse.ok();
        }else {
            return GenericResponse.ng("修改订单为已使用失败");
        }
    }

}

